import EventEmitter from 'eventemitter3'

/** 事件触发类 */
// class EventEmitter<
//     EventType extends string,
//     HandlerType extends (...args: any[]) => void = (...args: any[]) => void
// > {
//     /** 事件处理器 */
//     private _handlers: {
//         [key in EventType]?: HandlerType[]
//     } = {}
//     /** 添加事件处理器 */
//     on(eventType: EventType, handler: HandlerType, once = false) {
//         this._handlers[eventType] = this._handlers[eventType] || []
//         const exists = this._handlers[eventType].includes(handler)
//         if (!exists) {
//             this._handlers[eventType].push(handler)
//         }
//     }

//     /** 触发事件 */
//     emit(eventType: EventType, ...args: Parameters<HandlerType>) {
//         // console.log('emit', eventType, args)
//         this._handlers[eventType]?.forEach((handler) => handler(...args))
//     }

//     /** 移除事件 */
//     off(eventType: EventType, handler: HandlerType) {
//         this._handlers[eventType] = this._handlers[eventType]?.filter(
//             (h) => h !== handler
//         )
//     }
// }

export type IKeyboardEventType = 'keydown' | 'keyup' | 'keypress' | 'pressingChange'
class Keyboard extends EventEmitter<IKeyboardEventType> {
    /** 正在按下的键 */
    private _pressingKeys: string[] = []

    constructor() {
        super()
        this.init()
    }

    /** 初始化 */
    init() {
        document.addEventListener('keydown', (e) => this._handleKeyDown(e))
        document.addEventListener('keyup', (e) => this._handleKeyUp(e))
        document.addEventListener('keypress', (e) => this._handleKeyPress(e))
    }

    /** 事件处理函数 */
    _handleKeyDown(e: KeyboardEvent) {
        this._pressingKeys.push(e.key)
        this.emit('keydown', e)
        this.emit('pressingChange', this._pressingKeys)
    }
    _handleKeyUp(e: KeyboardEvent) {
        this._pressingKeys = this._pressingKeys.filter((key) => key !== e.key)
        this.emit('keyup', e)
        this.emit('pressingChange', this._pressingKeys)
    }
    _handleKeyPress(e: KeyboardEvent) {
        this.emit('keypress', e)
    }
    /** 销毁 */
    destroy() {
        document.removeEventListener('keydown', this._handleKeyDown)
        document.removeEventListener('keyup', this._handleKeyUp)
    }
    /** 获取当前按下的按键列表 */
    get pressingKeys() {
        return this._pressingKeys
    }
    /** 是否按下Shift键 */
    get isShiftPressed() {
        return this._pressingKeys.includes('Shift')
    }
    /** 是否按下Ctrl键 */
    get isCtrlPressed() {
        return this._pressingKeys.includes('Ctrl')
    }
    /** 是否按下Alt键 */
    get isAltPressed() {
        return this._pressingKeys.includes('Alt')
    }
}

export type IMouseEventType =
    | 'click'
    | 'dblclick'
    | 'mousedown'
    | 'mouseup'
    | 'mousemove'
    | 'mouseenter'
    | 'mouseleave'
    | 'mouseover'
    | 'mouseout'
    | 'contextmenu'
export class Mouse extends EventEmitter<IMouseEventType> {
    _eventNames: IMouseEventType[] = [
        'click',
        'dblclick',
        'mousedown',
        'mouseup',
        'mousemove',
        'mouseenter',
        'mouseleave',
        'mouseover',
        'mouseout',
        'contextmenu'
    ]
    /** 鼠标提示文本 */
    _textDom = document.createElement('div')
    _textDomContent = ''

    /** 存储，在鼠标按下移动的时候可以把拖拽的数据存储起来 */
    storage = new Map()
    /** 是否正在拖拽 */
    isDragging = false

    constructor() {
        super()
        this.init()
    }

    init() {
        // 设置鼠标提示文本的样式
        document.body.appendChild(this._textDom)
        this._textDom.className = `mouse-text hidden absolute bg-white z-9999
            border border-solid border-gray-300 rounded-md shadow-md
            px-2 py-0.5 top-0 left-0
            text-xs whitespace-nowrap
            `
        this.on('mousemove', (e) => this._textDomMouseMoveHandler(e))

        // 注册鼠标事件
        this._eventNames.forEach((eventName) => {
            document.addEventListener(eventName, this._handler(eventName))
        })
    }

    _textDomMouseMoveHandler(e: MouseEvent) {
        // console.log(this._textDom)
        if (!this._textDomContent) return
        // this._textDom.style.left = e.clientX + 12 + 'px'
        // this._textDom.style.top = e.clientY + 16 + 'px'
        this._textDom.style.transform = `translate(${e.clientX + 12}px, ${e.clientY + 16}px)`
    }

    _handler(eventName: IMouseEventType) {
        return (e: MouseEvent) => {
            this.emit(eventName, e)
        }
    }

    // 设置鼠标指针样式
    setText(text = '') {
        this._textDomContent = text
        this._textDom.textContent = text
        if (text) {
            this._textDom.style.display = 'block'
        } else {
            this._textDom.style.display = 'none'
        }
    }
}

export const keyboard = new Keyboard()
export const mouse = new Mouse()

// mouse.setCursor('move')

// console.log(mouse)

// mouse.setText('复制')
